package com.droid.lib.controls.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.ColorRes;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.AdapterView;
import android.widget.LinearLayout;

import com.droid.lib.controls.R;

import java.util.ArrayList;

/**
 * Created by Dikaros on 2016/5/20.
 */
@SuppressLint("ClickableViewAccessibility")
public class BottomNavigationBar extends LinearLayout {

	private float mBaseWight;
	private float mDownWight;
	private float mDownHeight;
	private ScaleAnimation scaleAnimation;
	private float zoomScale = 1.03f;
	private int zoomDuration = 200;
	// 控件宽度
	private int WIDTH;
	// 控件高度
	private int HEIGHT;
	// 画笔
	private Paint paint;
	private GestureDetector gestureDetector;
	private boolean animationRunning = false;
	private Bitmap originBitmap;
	private int rippleAlpha = 90;
	private int rippleDuration = 400;

	private int timer = 0;
	private int timerEmpty = 0;
	private int durationEmpty = -1;
	private float x = -1;
	private float y = -1;
	private OnRippleCompleteListener onCompletionListener;
	private int ripplePadding;
	private float radiusMax = 0;
	private Handler canvasHandler;
	private int frameRate = 10;
	private int rippleColor;

	public BottomNavigationBar(Context context) {
		super(context);
		init();

	}

	/**
	 * 底部的显示模式
	 */
	public enum NavShowType {
		NORMAL, // 普通模式，包含文字和图片
		NO_TEXT, // 无文字模式
		NO_IMAGE, // 无图模式
		CHECKED_SHOW_TEXT // 普通无文字 选中出现文字
	}

	public static final int DEFAULT_UNCHECKED_IMAGE = R.drawable.ic_android_black_24dp;
	public static final int DEFAULT_CHECKED_IMAGE = R.drawable.ic_android_green_24dp;

	public static final int DEFAULT_CHECKED_TEXT = 0xff138768;
	public static final int DEFAULT_UNCHECKED_TEXT = 0xff747575;

	NavShowType type = NavShowType.NORMAL;

	public void setType(NavShowType type) {
		this.type = type;
		boolean tv = true, iv = true;
		switch (type) {
		case NORMAL:
			tv = true;
			iv = true;
			break;
		case NO_IMAGE:
			tv = true;
			iv = false;
			break;
		case NO_TEXT:
			tv = false;
			iv = true;
			break;
		case CHECKED_SHOW_TEXT:
			tv = false;
			iv = true;
		}
		for (NavigationItem item : items) {
			item.setTextVisible(tv);
			item.setImageVisible(iv);
			item.showView();
		}
		if (type == NavShowType.CHECKED_SHOW_TEXT) {
			items.get(currentChecked).setTextVisible(true);
		}
	}

	// 当前被选中的元素
	int currentChecked = 0;

	public BottomNavigationBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
		TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BottomNavigationBar);
		String t = a.getString(R.styleable.BottomNavigationBar_show_type);
		if (t == null) {
			setType(NavShowType.NORMAL);
		} else {
			if (t.equals("1")) {
				setType(NavShowType.NO_TEXT);

			} else if (t.equals("2")) {
				setType(NavShowType.NO_IMAGE);

			} else if (t.equals("3")) {
				setType(NavShowType.CHECKED_SHOW_TEXT);

			} else if (t.equals("0")) {
				setType(NavShowType.NORMAL);

			}
		}
		mBaseWight = getRight();
		textCheckdColor = a.getColor(R.styleable.BottomNavigationBar_textCheckedColor, textCheckdColor);
		textUnCheckColor = a.getColor(R.styleable.BottomNavigationBar_textUnCheckedColor, textUnCheckColor);
		a.recycle();
	}

	public BottomNavigationBar(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init();
	}

	public void addItemView(final NavigationItem item) {
		boolean tv = true, iv = true;
		switch (type) {
		case NORMAL:
			tv = true;
			iv = true;
			break;
		case NO_IMAGE:
			tv = true;
			iv = false;
			break;
		case NO_TEXT:
			tv = false;
			iv = true;
			break;
		case CHECKED_SHOW_TEXT:
			tv = false;
			iv = true;
		}
		item.setTextVisible(tv);
		item.setImageVisible(iv);
		item.setTextCheckedColor(textCheckdColor);
		item.setTextUnCheckedColor(textUnCheckColor);
		items.add(item);
		final int i = items.size() - 1;
		item.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (gestureDetector.onTouchEvent(event)) {
					mDownHeight = item.getHeight() / 2;
					mBaseWight = getRight();
					mDownWight = i * (mBaseWight / items.size()) + (mBaseWight / items.size() / 2);
					event.setLocation(mDownWight, mDownHeight);
					animateRipple(event);
					sendClickEvent(false);
				}
				return false;
			}
		});
		item.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// 这个item在集合中的第几个
				int index = i;
				// 如果不是当前的view
				boolean noChecked = index != currentChecked;
				if (noChecked) {
					// 改变上一个view

					items.get(currentChecked).changeView();
					if (type == NavShowType.CHECKED_SHOW_TEXT) {
						items.get(currentChecked).setTextVisible(false);
					}
					currentChecked = index;
					if (onItemViewSelectedListener != null) {
						mBaseWight = getRight();
						mDownHeight = item.getHeight() / 2;
						mDownWight = index * (mBaseWight / items.size()) + (mBaseWight / items.size() / 2);
						// float targetRadius = Math.max(tempRadius,
						// mMaxRadius);
						createAnimation(mBaseWight, mDownHeight);
						sendClickEvent(false);
						onItemViewSelectedListener.onItemClcik(v, index);
					}
					// 改变当前点击的view
					item.changeView();
					if (type == NavShowType.CHECKED_SHOW_TEXT) {
						item.setTextVisible(true);
					}
				}
			}
		});

		addView(item);
		if (items.size() == 1) {
			item.changeView();
		}
		item.showView();
	}

	int textCheckdColor = DEFAULT_CHECKED_TEXT;
	int textUnCheckColor = DEFAULT_UNCHECKED_TEXT;

	/**
	 * 增加
	 *
	 * @param text
	 */
	public void addItemView(String text, int textCheckdColor, int textUnCheckColor, int imageCheckedResource,
			int imageUnCheckedResource) {
		NavigationItem item = new NavigationItem(getContext(), textCheckdColor, textUnCheckColor, imageCheckedResource,
				imageUnCheckedResource);
		item.getmTextView().setText(text);
		addItemView(item);
	}

	public void setTextColor(int checkedColor, int unCheckedColor) {
		this.textCheckdColor = checkedColor;
		this.textUnCheckColor = unCheckedColor;
		for (NavigationItem item : items) {
			item.setTextCheckedColor(checkedColor);
			item.setTextUnCheckedColor(unCheckedColor);
			item.showView();
		}
	}

	public void setTextColor(int checkedColor) {
		this.textCheckdColor = checkedColor;
		for (NavigationItem item : items) {
			item.setTextCheckedColor(checkedColor);
			item.setTextUnCheckedColor(textUnCheckColor);
			item.showView();
		}
	}

	public void setTextColorRes(int checkedColorId, int unCheckedColorId) {
		setTextColor(getResources().getColor(checkedColorId), getResources().getColor(unCheckedColorId));
	}

	public void setTextColorRes(int checkedColorId) {
		setTextColor(getResources().getColor(checkedColorId));
	}

	// public void addItemView(String text) {
	// NavigationItem item = new NavigationItem(getContext(), textCheckdColor,
	// textUnCheckColor, DEFAULT_CHECKED_IMAGE, DEFAULT_UNCHECKED_IMAGE);
	// item.getmTextView().setText(text);
	// addItemView(item);
	// }

	public void addItemView(String text, int imageCheckedResource, int imageUnCheckedResource) {
		addItemView(text, textCheckdColor, textUnCheckColor, imageCheckedResource, imageUnCheckedResource);
	}

	OnItemViewSelectedListener onItemViewSelectedListener;

	public void setOnItemViewSelectedListener(OnItemViewSelectedListener onItemViewSelectedListener) {
		this.onItemViewSelectedListener = onItemViewSelectedListener;
	}

	// item列表
	ArrayList<NavigationItem> items = new ArrayList<>();

	public interface OnItemViewSelectedListener {
		public void onItemClcik(View v, int index);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.widget.TextView#onDraw(android.graphics.Canvas)
	 */
	@Override
	protected void onDraw(final Canvas canvas) {
		super.onDraw(canvas);
		if (animationRunning) {
			canvas.save();
			if (rippleDuration <= timer * frameRate) {
				animationRunning = false;
				timer = 0;
				durationEmpty = -1;
				timerEmpty = 0;
				// There is problem on Android M where canvas.restore() seems to
				// be called automatically
				// For now, don't call canvas.restore() manually on Android M
				// (API 23)
				if (Build.VERSION.SDK_INT != 23) {
					canvas.restore();
				}
				invalidate();
				if (onCompletionListener != null)
					onCompletionListener.onComplete(BottomNavigationBar.this);
				return;
			} else
				canvasHandler.postDelayed(runnable, frameRate);

			if (timer == 0)
				canvas.save();

			float radius = (radiusMax * (((float) timer * frameRate) / rippleDuration));
			canvas.drawCircle(x, y, radius, paint);
			if (radius >= mBaseWight) {

			}
			paint.setColor(rippleColor);
//			paint.setAlpha((int) rippleAlpha);
			  paint.setAlpha((int) (rippleAlpha - ((rippleAlpha) * (((float) timer * frameRate) / rippleDuration))));
			timer++;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.view.View#onSizeChanged(int, int, int, int)
	 */
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		// mMaxRadius = (float) Math.sqrt(w * w + h * h);
		WIDTH = w;
		HEIGHT = h;

		scaleAnimation = new ScaleAnimation(1.0f, zoomScale, 1.0f, zoomScale, w / 2, h / 2);
		scaleAnimation.setDuration(zoomDuration);
		scaleAnimation.setRepeatMode(Animation.REVERSE);
		scaleAnimation.setRepeatCount(1);
	}

	private void init() {
		if (isInEditMode())
			return;
		rippleColor = Color.WHITE;
		ripplePadding = 0;
		canvasHandler = new Handler();
		zoomScale = 1.03f;
		zoomDuration = 200;
		paint = new Paint();
		paint.setAntiAlias(true);
		paint.setStyle(Paint.Style.FILL);
		paint.setColor(rippleColor);
		paint.setAlpha(rippleAlpha);
		this.setWillNotDraw(false);

		gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
			@Override
			public void onLongPress(MotionEvent event) {
				super.onLongPress(event);
				animateRipple(event);
				sendClickEvent(true);
			}

			@Override
			public boolean onSingleTapConfirmed(MotionEvent e) {
				return true;
			}

			@Override
			public boolean onSingleTapUp(MotionEvent e) {
				return true;
			}
		});

		this.setDrawingCacheEnabled(true);
		this.setClickable(true);
	}

	/**
	 * Launch Ripple animation for the current view with a MotionEvent
	 *
	 * @param event
	 *            MotionEvent registered by the Ripple gesture listener
	 */
	public void animateRipple(MotionEvent event) {
		createAnimation(event.getX(), event.getY());
	}

	/**
	 * Create Ripple animation centered at x, y
	 *
	 * @param x
	 *            Horizontal position of the ripple center
	 * @param y
	 *            Vertical position of the ripple center
	 */
	private void createAnimation(float x, float y) {
		if (this.isEnabled() && !animationRunning) {
			this.startAnimation(scaleAnimation);
			radiusMax = Math.max(WIDTH, HEIGHT);
			// radiusMax /= 2;
			radiusMax -= ripplePadding;
			this.x = x;
			this.y = y;
			animationRunning = true;

			invalidate();
		}
	}

	/**
	 * Send a click event if parent view is a Listview instance
	 *
	 * @param isLongClick
	 *            Is the event a long click ?
	 */
	private void sendClickEvent(final Boolean isLongClick) {
		if (getParent() instanceof AdapterView) {
			final AdapterView adapterView = (AdapterView) getParent();
			final int position = adapterView.getPositionForView(this);
			final long id = adapterView.getItemIdAtPosition(position);
			if (isLongClick) {
				if (adapterView.getOnItemLongClickListener() != null)
					adapterView.getOnItemLongClickListener().onItemLongClick(adapterView, this, position, id);
			} else {
				if (adapterView.getOnItemClickListener() != null)
					adapterView.getOnItemClickListener().onItemClick(adapterView, this, position, id);
			}
		}
	}

	public void setOnRippleCompleteListener(OnRippleCompleteListener listener) {
		this.onCompletionListener = listener;
	}

	/**
	 * Defines a callback called at the end of the Ripple effect
	 */
	public interface OnRippleCompleteListener {
		void onComplete(BottomNavigationBar rippleView);

		void onInvalidateBefore();
	}

	private final Runnable runnable = new Runnable() {
		@Override
		public void run() {
			invalidate();
		}
	};


	/**
	 * Set Ripple color, default is #FFFFFF
	 *
	 * @param rippleColor
	 *            New color resource
	 */
	@ColorRes
	public void setRippleColor(int rippleColor) {
		this.rippleColor = rippleColor;
	}

	public int getRippleColor() {
		return rippleColor;
	}
}
